package xyz.erupt.flow.utils;

import xyz.erupt.core.exception.EruptApiErrorTip;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * @author PP
 * @version 1.0
 * @project erupt-flow
 * @description 流程编号生成工具
 * @date 2024/10/14 10:46:17
 */
public class FlowUniqueCodeUtil {
    // 使用固定的AES密钥（在实际应用中，请妥善管理密钥）
    private static final String SECRET_KEY = "erupt_flow_pro_1"; // 16个字符的密钥

    /***
     * @description TODO 加密生成流程编号
     * @param inputId
     * @return java.lang.String
     * @author PP
     * @date 2024/10/14 10:51:06
     */
    public static String encrypt(String inputId) {
        try{
            SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encryptedBytes = cipher.doFinal(inputId.getBytes());

            // 将加密后的字节数组编码为Base64
            String base64Encoded = Base64.getEncoder().encodeToString(encryptedBytes);

            // 将Base64编码的字符串转换为只包含字母和数字的字符串
            return base64ToAlphanumeric(base64Encoded);
        }catch (Exception e){
            throw new EruptApiErrorTip(e.getMessage());
        }

    }


   /***
    * @description TODO 解密查找原始流程id
    * @param uniqueId
    * @return java.lang.String
    * @author PP
    * @date 2024/10/14 10:51:38
    */
    public static String decrypt(String uniqueId){
        try{
            SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);

            // 将字母数字编码的字符串转换回Base64
            String base64Encoded = alphanumericToBase64(uniqueId);
            byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(base64Encoded));
            return new String(decryptedBytes);
        }catch (Exception e){
            throw new EruptApiErrorTip(e.getMessage());
        }

    }

    // 将Base64编码的字符串转换为仅包含字母和数字的字符串
    private static String base64ToAlphanumeric(String base64) {
        StringBuilder alphanumeric = new StringBuilder();
        for (char c : base64.toCharArray()) {
            if (Character.isLetterOrDigit(c)) {
                alphanumeric.append(c);
            }
        }
        // 确保返回字符串的长度是偶数，以便能正确解码
        while (alphanumeric.length() % 4 != 0) {
            alphanumeric.append('A'); // 填充字符，您可以选择其他字符
        }
        return alphanumeric.toString();
    }

    // 将仅包含字母和数字的字符串转换回Base64
    private static String alphanumericToBase64(String alphanumeric) {
        // 由于我们使用的填充字符是'A'，因此将其替换为'='
        StringBuilder base64 = new StringBuilder();
        for (char c : alphanumeric.toCharArray()) {
            base64.append(c);
        }
        return base64.toString();
    }

}
